package be.ipl.uccimpl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import javax.ejb.EJB;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Stateless;

import be.ipl.dao.CaseDao;
import be.ipl.dao.JetonDao;
import be.ipl.dao.JoueurDao;
import be.ipl.dao.PartieDao;
import be.ipl.dao.TableauDao;
import be.ipl.domaine.Case;
import be.ipl.domaine.Jeton;
import be.ipl.domaine.Joueur;
import be.ipl.domaine.Partie;
import be.ipl.domaine.Tableau;
import be.ipl.exception.ArgumentInvalideException;
import be.ipl.ucc.GestionTableau;
import be.ipl.util.Util;


/**
 * The Class GestionTableauImpl.
 */
@Stateless
public class GestionTableauImpl implements GestionTableau{

	/** The partie dao. */
	@EJB
	PartieDao partieDao;
	
	/** The tableau dao. */
	@EJB
	TableauDao tableauDao;
	
	/** The case dao. */
	@EJB
	CaseDao caseDao;
	
	/** The joueur dao. */
	@EJB
	private JoueurDao joueurDao;
	
	/** The jeton dao. */
	@EJB
	private JetonDao jetonDao;
	
	/** The liste parties suspendues. */
	private Map<Integer, AtomicInteger> listePartiesSuspendues = new HashMap<Integer, AtomicInteger>();

	/** The partie. */
	private Partie partie;
	
	
	@Override
	public Partie chargerTout(Partie partie) {
		try {
			Util.checkObject(partie);
		} catch (ArgumentInvalideException e) {
			e.printStackTrace();
		}
		if (partie.getId_partie() == 0)
			return partie;
		partie = partieDao.chargerJetonsEtTableaux(partie);
		for (Tableau tab : partie.getTableaux()) {
			tab = tableauDao.chargerTableaux(tab);
		}
		return partie;
	}
	
	
	@Override
	public boolean placerJeton(int idPartie, int positionCase, int valeurJeton,
			String login) {
		try {
			Util.checkPositive(idPartie);
			Util.checkPositive(positionCase);
			Util.checkPositive(valeurJeton);
			Util.checkString(login);
		} catch (ArgumentInvalideException e) {
			e.printStackTrace();
		}
		partie = partieDao.rechercher(idPartie);
		partie = chargerTout(partie);
		Jeton jeton = jetonDao.rechercherJeton(valeurJeton);
		boolean result = partie.placerJeton(positionCase, jeton, login);
		partie = partieDao.mettreAJour(partie);
		return result;
	}
	

	@Override
	@Lock(LockType.READ)
	public Map<Integer, Integer> casesOccupes(int partieId, String login) {
		try {
			Util.checkPositive(partieId);
			Util.checkString(login);
		} catch (ArgumentInvalideException e) {
			e.printStackTrace();
		}
		partie = partieDao.rechercher(partieId);
		partie = chargerTout(partie);
		Joueur joueur = joueurDao.rechercher(login);
		return partie.casesOccupes(joueur);
	}
	
	
	@Override
	@Lock(LockType.READ)
	public List<Integer> casesPossibles(int idPartie, int de, String login) {
		try {
			Util.checkPositive(idPartie);
			Util.checkPositive(de);
			Util.checkString(login);
		} catch (ArgumentInvalideException e) {
			e.printStackTrace();
		}
		partie = partieDao.rechercher(idPartie);
		partie = chargerTout(partie);
		List<Integer> list = partie.casesPossibles(de, login);
		partie = partieDao.mettreAJour(partie);
		return list;
	}
	
	
	@Override
	@Lock(LockType.READ)
	public Map<String, String> obtenirScore(int idPartie) {
		try {
			Util.checkPositive(idPartie);
		} catch (ArgumentInvalideException e) {
			e.printStackTrace();
		}
		partie = partieDao.recharger(idPartie);
		return partie.classement();
	}
	
	@Override
	public List<Jeton> obtenirMainJoueur(int partieId, String login) {
		try {
			Util.checkPositive(partieId);
			Util.checkString(login);
		} catch (ArgumentInvalideException e) {
			e.printStackTrace();
		}
		partie = partieDao.rechercher(partieId);
		partie = chargerTout(partie);
		List<Jeton> liste = new ArrayList<Jeton>();
		List<Case> listeOccupe = new ArrayList<Case>();
		for (int i = 0; i < min(partie.getIndiceProchain()-1,12); i++) {
			liste.add(partie.getJetons().get(i));
		}
		for (Tableau tab : partie.getTableaux()) {
			if (tab.getJoueur().getLogin().compareTo(login) == 0) {
				listeOccupe = caseDao.listerCase(tab);
				for (int i = 0; i < listeOccupe.size(); i++) {
					int j=0;
					while(j<liste.size()){
						if(liste.get(j).getNombre() == listeOccupe.get(i).getJeton().getNombre()){
							liste.remove(j);
						}
						j++;
					}
				}
			}
		}
		System.out.println("je renvois la liste");
		return liste;
	}
	
	/**
	 * Min.
	 *
	 * @param i the i
	 * @param j the j
	 * @return the int
	 */
	private int min(int i, int j) {
		return i > j?j:i;
	}

	
	public boolean partieEstEnCours(int idPartie) {
		try {
			Util.checkPositive(idPartie);
		} catch (ArgumentInvalideException e) {
			e.printStackTrace();
		}
		partie = partieDao.rechercher(idPartie);
		boolean result = partie.partieEstEnCours();
		return result;
	}
}
